/*
* Copyright 2011 Henry Coles
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package org.pitest.maven;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.AdditionalAnswers.returnsFirstArg;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.model.Build;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.mockito.Mockito;
import org.pitest.functional.predicate.Predicate;
import org.pitest.functional.prelude.Prelude;
import org.pitest.mutationtest.config.ConfigOption;
import org.pitest.mutationtest.config.ReportOptions;
import org.pitest.util.Unchecked;
public class MojoToReportOptionsConverterTest extends BasePitMojoTest {
private MojoToReportOptionsConverter testee;
private SurefireConfigConverter surefireConverter;
@Override
public void setUp() throws Exception {
super.setUp();
Plugin surefire = new Plugin();
surefire.setGroupId("org.apache.maven.plugins");
surefire.setArtifactId("maven-surefire-plugin");
this.surefireConverter = Mockito.mock(SurefireConfigConverter.class);
List<Plugin> mavenPlugins = Collections.singletonList(surefire);
when(this.project.getBuildPlugins()).thenReturn(mavenPlugins);
Build build = new Build();
build.setOutputDirectory("");
when(this.project.getBuild()).thenReturn(build);
}
public void testsParsesReportDir() {
final ReportOptions actual = parseConfig("<reportsDirectory>Foo</reportsDirectory>");
assertEquals(new File("Foo").getAbsolutePath(), actual.getReportDir());
}
public void testCreatesPredicateFromListOfTargetClassGlobs() {
final String xml = "<targetClasses>" + //
" <param>foo*</param>" + //
" <param>bar*</param>" + //
" </targetClasses>";
final ReportOptions actual = parseConfig(xml);
final Predicate<String> actualPredicate = actual.getTargetClassesFilter();
assertTrue(actualPredicate.apply("foo_anything"));
assertTrue(actualPredicate.apply("bar_anything"));
assertFalse(actualPredicate.apply("notfoobar"));
}
public void testUsesSourceDirectoriesFromProject() {
when(this.project.getCompileSourceRoots()).thenReturn(Arrays.asList("src"));
when(this.project.getTestCompileSourceRoots()).thenReturn(
Arrays.asList("tst"));
final ReportOptions actual = parseConfig("");
assertEquals(Arrays.asList(new File("src"), new File("tst")),
actual.getSourceDirs());
}
public void testParsesMaxDependencyDistance() {
final ReportOptions actual = parseConfig("<maxDependencyDistance>42</maxDependencyDistance>");
assertEquals(42, actual.getDependencyAnalysisMaxDistance());
}
public void testParsesExcludedRunners() {
String runner = "org.springframework.test.context.junit4.SpringJUnit4ClassRunner";
final ReportOptions actual = parseConfig("<excludedRunners><param>" + runner + "</param></excludedRunners>");
assertThat(actual.getExcludedRunners()).hasSize(1).containsExactly(runner);
}
public void testParsesListOfJVMArgs() {
final String xml = "<jvmArgs>" + //
" <param>foo</param>" + //
" <param>bar</param>" + //
" </jvmArgs>";
final ReportOptions actual = parseConfig(xml);
assertEquals(Arrays.asList("foo", "bar"), actual.getJvmArgs());
}
public void testParsesListOfMutationOperators() {
final String xml = "<mutators>" + //
" <param>foo</param>" + //
" <param>bar</param>" + //
" </mutators>";
final ReportOptions actual = parseConfig(xml);
assertEquals(Arrays.asList("foo", "bar"), actual.getMutators());
}
public void testParsersMutateStaticInitializersFlag() {
assertTrue(parseConfig(
"<mutateStaticInitializers>true</mutateStaticInitializers>")
.isMutateStaticInitializers());
assertFalse(parseConfig(
"<mutateStaticInitializers>false</mutateStaticInitializers>")
.isMutateStaticInitializers());
}
public void testParsesNumberOfThreads() {
final ReportOptions actual = parseConfig("<threads>42</threads>");
assertEquals(42, actual.getNumberOfThreads());
}
public void testParsesTimeOutFactor() {
final ReportOptions actual = parseConfig("<timeoutFactor>1.32</timeoutFactor>");
assertEquals(1.32f, actual.getTimeoutFactor(), 0.1);
}
public void testParsesTimeOutConstant() {
final ReportOptions actual = parseConfig("<timeoutConstant>42</timeoutConstant>");
assertEquals(42, actual.getTimeoutConstant());
}
public void testParsesListOfTargetTestClassGlobs() {
final String xml = "<targetTests>" + //
" <param>foo*</param>" + //
" <param>bar*</param>" + //
" </targetTests>";
final ReportOptions actual = parseConfig(xml);
final Predicate<String> actualPredicate = actual.getTargetTestsFilter();
assertTrue(actualPredicate.apply("foo_anything"));
assertTrue(actualPredicate.apply("bar_anything"));
assertFalse(actualPredicate.apply("notfoobar"));
}
public void testParsesListOfExcludedClassGlobsAndApplyTheseToTests() {
final String xml = "<excludedClasses>" + //
" <param>foo*</param>" + //
" </excludedClasses>" + //
" <targetTests>" + //
" <param>foo*</param>" + //
" <param>bar*</param>" + //
" </targetTests>";
final ReportOptions actual = parseConfig(xml);
final Predicate<String> testPredicate = actual.getTargetTestsFilter();
assertFalse(testPredicate.apply("foo_anything"));
assertTrue(testPredicate.apply("bar_anything"));
}
public void testParsesListOfExcludedClassGlobsAndApplyTheseToTargets() {
final String xml = "<excludedClasses>" + //
" <param>foo*</param>" + //
" </excludedClasses>" + //
" <targetClasses>" + //
" <param>foo*</param>" + //
" <param>bar*</param>" + //
" </targetClasses>";
final ReportOptions actual = parseConfig(xml);
final Predicate<String> targetPredicate = actual.getTargetClassesFilter();
assertFalse(targetPredicate.apply("foo_anything"));
assertTrue(targetPredicate.apply("bar_anything"));
}
public void testDefaultsLoggingPackagesToDefaultsDefinedByDefaultMutationConfigFactory() {
final ReportOptions actual = parseConfig("");
assertEquals(ReportOptions.LOGGING_CLASSES, actual.getLoggingClasses());
}
public void testParsesListOfClassesToAvoidCallTo() {
final String xml = "<avoidCallsTo>" + //
" <param>foo</param>" + //
" <param>bar</param>" + //
" <param>foo.bar</param>" + //
" </avoidCallsTo>";
final ReportOptions actual = parseConfig(xml);
assertEquals(Arrays.asList("foo", "bar", "foo.bar"),
actual.getLoggingClasses());
}
public void testParsesCommaListOfExcludedMethods() {
final String xml = "<excludedMethods>" + //
" <param>foo*</param>" + //
" <param>bar*</param>" + //
" <param>car</param>" + //
" </excludedMethods>";
final ReportOptions actual = parseConfig(xml);
final Predicate<String> actualPredicate = Prelude.or(actual
.getExcludedMethods());
assertTrue(actualPredicate.apply("foox"));
assertTrue(actualPredicate.apply("barx"));
assertTrue(actualPredicate.apply("car"));
assertFalse(actualPredicate.apply("carx"));
}
public void testParsesVerboseFlag() {
assertTrue(parseConfig("<verbose>true</verbose>").isVerbose());
assertFalse(parseConfig("<verbose>false</verbose>").isVerbose());
}
public void testParsesDetectInlineCodeFlag() {
assertTrue(parseConfig("<detectInlinedCode>true</detectInlinedCode>")
.isDetectInlinedCode());
assertFalse(parseConfig("<detectInlinedCode>false</detectInlinedCode>")
.isDetectInlinedCode());
}
public void testDefaultsToHtmlReportWhenNoOutputFormatsSpecified() {
final ReportOptions actual = parseConfig("");
assertEquals(new HashSet<String>(Arrays.asList("HTML")),
actual.getOutputFormats());
}
public void testParsesListOfOutputFormatsWhenSupplied() {
final String xml = "<outputFormats>" + //
" <param>HTML</param>" + //
" <param>CSV</param>" + //
" </outputFormats>";
final ReportOptions actual = parseConfig(xml);
assertEquals(new HashSet<String>(Arrays.asList("HTML", "CSV")),
actual.getOutputFormats());
}
public void testObeysFailWhenNoMutationsFlagWhenPackagingTypeIsNotPOM() {
when(this.project.getModel()).thenReturn(new Model());
assertTrue(parseConfig("<failWhenNoMutations>true</failWhenNoMutations>")
.shouldFailWhenNoMutations());
assertFalse(parseConfig("<failWhenNoMutations>false</failWhenNoMutations>")
.shouldFailWhenNoMutations());
}
public void testParsesTestGroupsToExclude() {
final ReportOptions actual = parseConfig("<excludedGroups><value>foo</value><value>bar</value></excludedGroups>");
assertEquals(Arrays.asList("foo", "bar"), actual.getGroupConfig()
.getExcludedGroups());
}
public void testParsesTestGroupsToInclude() {
final ReportOptions actual = parseConfig("<includedGroups><value>foo</value><value>bar</value></includedGroups>");
assertEquals(Arrays.asList("foo", "bar"), actual.getGroupConfig()
.getIncludedGroups());
}
public void testMaintainsOrderOfClassPath() {
final ReportOptions actual = parseConfig("<includedGroups><value>foo</value><value>bar</value></includedGroups>");
assertEquals(this.classPath, actual.getClassPathElements());
}
public void testParsesMutationUnitSize() {
final ReportOptions actual = parseConfig("<mutationUnitSize>50</mutationUnitSize>");
assertEquals(50, actual.getMutationUnitSize());
}
public void testDefaultsMutationUnitSizeToCorrectValue() {
final ReportOptions actual = parseConfig("");
assertEquals(
(int) ConfigOption.MUTATION_UNIT_SIZE.getDefault(Integer.class),
actual.getMutationUnitSize());
}
public void testParsesTimeStampedReports() {
final ReportOptions actual = parseConfig("<timestampedReports>false</timestampedReports>");
assertEquals(false, actual.shouldCreateTimeStampedReports());
}
public void testParsesHistoryInputFile() {
final ReportOptions actual = parseConfig("<historyInputFile>foo</historyInputFile>");
assertEquals(new File("foo"), actual.getHistoryInputLocation());
}
public void testParsesHistoryOutputFile() {
final ReportOptions actual = parseConfig("<historyOutputFile>foo</historyOutputFile>");
assertEquals(new File("foo"), actual.getHistoryOutputLocation());
}
public void testParsesLocalHistoryFlag() {
when(this.project.getGroupId()).thenReturn("com.example");
when(this.project.getArtifactId()).thenReturn("foo");
when(this.project.getVersion()).thenReturn("0.1-SNAPSHOT");
final ReportOptions actual = parseConfig("<withHistory>true</withHistory>");
String expected = "com.example.foo.0.1-SNAPSHOT_pitest_history.bin";
assertThat(actual.getHistoryInputLocation().getAbsolutePath()).endsWith(expected);
}
public void testParsesLineCoverageExportFlagWhenSet() {
final ReportOptions actual = parseConfig("<exportLineCoverage>true</exportLineCoverage>");
assertTrue(actual.shouldExportLineCoverage());
}
public void testParsesLineCoverageExportFlagWhenNotSet() {
final ReportOptions actual = parseConfig("<exportLineCoverage>false</exportLineCoverage>");
assertFalse(actual.shouldExportLineCoverage());
}
public void testParsesEngineWhenSet() {
final ReportOptions actual = parseConfig("<mutationEngine>foo</mutationEngine>");
assertEquals("foo", actual.getMutationEngine());
}
public void testDefaultsJavaExecutableToNull() {
final ReportOptions actual = parseConfig("");
assertEquals(null, actual.getJavaExecutable());
}
public void testParsesJavaExecutable() {
final ReportOptions actual = parseConfig("<jvm>foo</jvm>");
assertEquals("foo", actual.getJavaExecutable());
}
public void testParsesExcludedClasspathElements()
throws DependencyResolutionRequiredException {
final String sep = File.pathSeparator;
final Set<Artifact> artifacts = new HashSet<Artifact>();
final Artifact dependency = Mockito.mock(Artifact.class);
when(dependency.getGroupId()).thenReturn("group");
when(dependency.getArtifactId()).thenReturn("artifact");
when(dependency.getFile()).thenReturn(
new File("group" + sep + "artifact" + sep + "1.0.0" + sep
+ "group-artifact-1.0.0.jar"));
artifacts.add(dependency);
when(this.project.getArtifacts()).thenReturn(artifacts);
when(this.project.getTestClasspathElements()).thenReturn(
Arrays.asList("group" + sep + "artifact" + sep + "1.0.0" + sep
+ "group-artifact-1.0.0.jar"));
final ReportOptions actual = parseConfig("<classpathDependencyExcludes>"
+ " <param>group:artifact</param>"
+ " </classpathDependencyExcludes>");
assertFalse(actual.getClassPathElements().contains(
"group" + sep + "artifact" + sep + "1.0.0" + sep
+ "group-artifact-1.0.0.jar"));
}
public void testParsesSurefireConfigWhenFlagSet() {
parseConfig("<parseSurefireConfig>true</parseSurefireConfig>");
verify(this.surefireConverter).update(any(ReportOptions.class),
any(Xpp3Dom.class));
}
public void testIgnoreSurefireConfigWhenFlagNotSet() {
parseConfig("<parseSurefireConfig>false</parseSurefireConfig>");
verify(this.surefireConverter, never()).update(any(ReportOptions.class),
any(Xpp3Dom.class));
}
public void testParsesCustomProperties() {
final ReportOptions actual = parseConfig("<pluginConfiguration><foo>foo</foo><bar>bar</bar></pluginConfiguration>");
assertEquals("foo", actual.getFreeFormProperties().get("foo"));
assertEquals("bar", actual.getFreeFormProperties().get("bar"));
}
private ReportOptions parseConfig(final String xml) {
try {
final String pom = createPomWithConfiguration(xml);
final AbstractPitMojo mojo = createPITMojo(pom);
@SuppressWarnings("unchecked")
Predicate<Artifact> filter = Mockito.mock(Predicate.class);
when(
this.surefireConverter.update(any(ReportOptions.class),
any(Xpp3Dom.class))).then(returnsFirstArg());
this.testee = new MojoToReportOptionsConverter(mojo,
this.surefireConverter, filter);
final ReportOptions actual = this.testee.convert();
return actual;
} catch (final Exception ex) {
throw Unchecked.translateCheckedException(ex);
}
}
}